package com.tang.portal.facade.admin.sys;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tang.framework.core.domain.HttpResult;
import com.tang.framework.core.model.LoginUser;
import com.tang.common.model.req.ReqId;
import com.tang.common.constant.Constant;
import com.tang.common.model.req.ReqIds;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.tang.service.admin.domain.SysUser;
import com.tang.service.admin.domain.SysUserRole;
import com.tang.service.admin.model.req.ReqSysUser;
import com.tang.service.admin.model.req.ReqSysUserAdd;
import com.tang.service.admin.model.res.ResSysUserTableItem;
import com.tang.service.admin.model.res.ResSysUserDetail;
import com.tang.service.admin.service.ISysUserRoleService;
import com.tang.service.admin.service.ISysUserService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.BeanUtils;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.tang.common.utils.excel.ExcelUtils.getStyleStrategy;

/**
 * @author tang jun liang
 * @Date ${gen.dateTime}
 */
@Service
public class SysUserFacade {

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysUserRoleService sysUserRoleService;


    /**
     * 后台用户表删除
     *
     * @param ids
     * @param currLoginUser
     * @return
     */
    public HttpResult<String> remove(ReqIds ids, LoginUser currLoginUser) {
        sysUserService.removeBatchByIds(ids.getIds());
        return HttpResult.ok();
    }

    /**
     * 后台用户表详情
     *
     * @param id
     * @param currLoginUser
     * @return
     */
    public HttpResult<ResSysUserDetail> detail(ReqId id, LoginUser currLoginUser) {
        SysUser sysUser = sysUserService.getById(id.getId());
        ResSysUserDetail resSysUserDetail = new ResSysUserDetail();
        BeanUtils.copyProperties(sysUser, resSysUserDetail);
        return HttpResult.ok(resSysUserDetail);
    }

    /**
     * 后台用户表列表
     *
     * @param reqSysUser
     * @param currLoginUser
     * @return
     */
    public HttpResult<IPage<ResSysUserTableItem>> list(ReqSysUser reqSysUser, LoginUser currLoginUser) {
        IPage<ResSysUserTableItem> page = sysUserService.selectJoinListPage(
                new Page<>(reqSysUser.getPageNum(), reqSysUser.getPageSize()),
                ResSysUserTableItem.class,
                new MPJLambdaWrapper<SysUser>()
                        .selectAll(SysUser.class)
                        .selectAs(SysUserRole::getRoleId, ResSysUserTableItem::getRoleId)
                        .leftJoin(SysUserRole.class, SysUserRole::getSysUserId, SysUser::getId)
                        .eq(StringUtils.isNotBlank(reqSysUser.getNickName()), SysUser::getNickName, reqSysUser.getNickName())
                        .eq(Objects.nonNull(reqSysUser.getStatus()), SysUser::getStatus, reqSysUser.getStatus())
                        .eq(Objects.nonNull(reqSysUser.getRoleId()), SysUserRole::getRoleId, reqSysUser.getRoleId())
        );
        return HttpResult.ok(page);
    }

    /**
     * 新增后台用户表
     *
     * @param sysUserAdd
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult<String> add(ReqSysUserAdd sysUserAdd) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserAdd, sysUser);
        sysUserService.saveOrUpdate(sysUser);
        SysUserRole sysUserRole = sysUserRoleService
                .lambdaQuery()
                .eq(SysUserRole::getSysUserId, sysUser.getId())
                .one();
        if (Objects.isNull(sysUserRole)) {
            sysUserRole = new SysUserRole();
            sysUserRole.setSysUserId(sysUser.getId());
        }
        sysUserRole.setRoleId(sysUserAdd.getRoleId());
        sysUserRoleService.saveOrUpdate(sysUserRole);
        return HttpResult.ok();
    }

    /**
     * 更新后台用户表
     *
     * @param sysUserAdd
     * @return
     */
    public HttpResult<String> update(ReqSysUserAdd sysUserAdd) {
        return add(sysUserAdd);
    }


    /**
     * 导出后台用户表表
     *
     * @param ids
     * @param httpServletResponse
     */
    @SneakyThrows
    public void export(ReqIds ids, HttpServletResponse httpServletResponse) {
        String fileName = URLEncoder.encode("后台用户.xlsx", StandardCharsets.UTF_8);
        // 设置响应体
        httpServletResponse.setContentType("application/vnd.ms-excel");
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setHeader("Content-disposition", "attachment;filename=" + fileName);
        List<SysUser> sysUserList = sysUserService
                .lambdaQuery()
                .in(!ids.getIds().isEmpty(), SysUser::getId, ids.getIds())
                .list();
        EasyExcel.write(httpServletResponse.getOutputStream(), SysUser.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .registerWriteHandler(getStyleStrategy())
                .sheet("后台用户").doWrite(sysUserList);
    }


    /**
     * 导入excel
     *
     * @param file
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult<String> importExcel(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        EasyExcel.read(inputStream, ReqSysUserAdd.class, new AnalysisEventListener<ReqSysUserAdd>() {
            final List<SysUser> sysUserList = new ArrayList<>();

            @Override
            public void invoke(ReqSysUserAdd sysUserAdd, AnalysisContext analysisContext) {
                SysUser sysUser = new SysUser();
                BeanUtils.copyProperties(sysUserAdd, sysUser);
                sysUserList.add(sysUser);
                if (sysUserList.size() == Constant.MAX_BATCH) {
                    sysUserService.saveBatch(sysUserList);
                    sysUserList.clear();
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                sysUserService.saveBatch(sysUserList);
            }
        });
        return HttpResult.ok();
    }

    /**
     * 导出模版
     *
     * @param httpServletResponse
     */
    @SneakyThrows
    public void exportTemplate(HttpServletResponse httpServletResponse) {
        String fileName = URLEncoder.encode("后台用户表导入模版.xlsx", StandardCharsets.UTF_8);
        // 设置响应体
        httpServletResponse.setContentType("application/vnd.ms-excel");
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setHeader("Content-disposition", "attachment;filename=" + fileName);
        EasyExcel.write(httpServletResponse.getOutputStream(), SysUser.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .registerWriteHandler(getStyleStrategy())
                .sheet("后台用户表").doWrite(List.of());
    }

}
